﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

using LowLevelGraphics.ColorSpaces;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Complex Skin Detection
    /// </summary>
    public class ComplexSkinDetection : MacroFilter, IBaseForeBackgroundColorFilter
    {
        /// <summary>
        /// Use this background color
        /// </summary>
        protected Color m_ColorBackground = Definitions.Black;

        /// <summary>
        /// Use this foreground color
        /// </summary>
        protected Color m_ColorForeground = Definitions.White;

        /// <summary>
        /// Initializes a new instance of the <see cref="ComplexSkinDetection"/> class.
        /// </summary>
        public ComplexSkinDetection()
        {
        }

        /// <summary>
        /// Now this can also be used to specify the iterations for the execution of each filter
        /// </summary>
        /// <param name="_bitmap"></param>
        /// <returns></returns>
        public override UnsafeBitmap Execute(UnsafeBitmap _bitmap)
        {
            DetectSkin(_bitmap);
            new Ranking().Execute(_bitmap);
            new Close().Execute(_bitmap);
            return _bitmap;
        }

        /// <summary>
        /// Detects the skin.
        /// </summary>
        /// <param name="_bitmap">The _bitmap.</param>
        private void DetectSkin(UnsafeBitmap _bitmap)
        {
            UnsafeBitmap bitmap = _bitmap;
            int nHeight = bitmap.Height;
            int nWidth = bitmap.Width;

            for (int y = 0; y < nHeight; y++)
            {
                for (int x = 0; x < nWidth; x++)
                {
                    Color color = bitmap.GetPixel(x, y);
                    int nSum = color.R + color.G + color.B + 1;

                    YCbCr ycbcr = new YCbCr(color);

                    double newVariable = (ycbcr.Cb + 0.6 * ycbcr.Cr);
                    if (
                        ycbcr.Y > 80
                        && ycbcr.Cb > -40 && ycbcr.Cb < -10
                        && ycbcr.Cr > 17 && ycbcr.Cr < 45
                        //(137 < ycbcr.Cr && ycbcr.Cr < 177)
                        // (77 < ycbcr.Cb && ycbcr.Cb < 127)
                        //&& (190 < newVariable && newVariable < 215)
                        )
                    {
                        bitmap.SetPixel(x, y, color);
                    }
                    else
                    {
                        bitmap.SetPixel(x, y, m_ColorBackground);
                    }
                }
            }
        }

        /// <summary>
        /// Gets or sets BackgroundColor
        /// </summary>
        public Color BackgroundColor
        {
            get { return m_ColorBackground; }
            set {m_ColorBackground = value;}
        }

        /// <summary>
        /// Gets or sets ForegroundColor
        /// </summary>
        public Color Foreground
        {
            get { return m_ColorForeground; }
            set { m_ColorForeground = value; }
        }
    }
}
